import requests

# GitHub API 基础 URL
GITHUB_API = "https://api.github.com"

def get_repo_default_branch(owner, repo):
    """获取仓库的默认分支名称"""
    url = f"{GITHUB_API}/repos/{owner}/{repo}"
    response = requests.get(url)
    if response.status_code != 200:
        print("❌ 无法获取仓库信息，请检查仓库名或网络。")
        return None
    return response.json()["default_branch"]

def get_dir_contents(owner, repo, branch, path=""):
    """获取指定路径下的目录内容"""
    url = f"{GITHUB_API}/repos/{owner}/{repo}/contents/{path}?ref={branch}"
    headers = {"Accept": "application/vnd.github.v3+json"}
    response = requests.get(url, headers=headers)
    if response.status_code != 200:
        print(f"❌ 无法获取路径内容: {path}")
        return None
    return response.json()

def display_and_choose(items, current_path=""):
    """显示列表并让用户选择，支持返回上一级"""
    folders = [item for item in items if item['type'] == 'dir']
    files = [item for item in items if item['type'] == 'file']

    choices = []  # 用于保存选项的列表

    print("\n📁 文件夹:")
    for item in folders:
        print(f"  {len(choices) + 1}. 📂 {item['name']}")
        choices.append(item)

    print("\n📄 文件:")
    for item in files:
        print(f"  {len(choices) + 1}. 📄 {item['name']}")
        choices.append(item)

    # 添加“返回上一级”选项（只有非根目录时显示）
    if current_path != "":
        print(f"\n  0. 🔙 返回上一级")

    if not choices:
        print("  （当前目录为空）")
        return None

    try:
        choice = int(input(f"\n👉 请输入序号 (0-{len(choices)}) 选择: "))
        if choice == 0:
            return "BACK"  # 特殊标记表示返回
        elif 1 <= choice <= len(choices):
            return choices[choice - 1]
        else:
            print("⚠️ 输入无效，请输入有效序号！")
            exit()
    except ValueError:
        print("⚠️ 请输入一个数字！")
        exit()
        return None

def main():
    print("🔍 GitHub 仓库文件浏览器（支持返回上一级）")
    print("💡 提示：输入序号进入文件夹或选择文件，输入 0 返回上一级\n")

    # 用户输入仓库信息
    owner = input("🔧 请输入仓库所有者（如：octocat）: ").strip()
    repo = input("🔧 请输入仓库名（如：Hello-World）: ").strip()

    # 获取默认分支
    print("🌐 正在获取默认分支...")
    branch = get_repo_default_branch(owner, repo)
    if not branch:
        return

    print(f"📦 仓库: {owner}/{repo} | 分支: {branch}")

    # 从根目录开始
    current_path = ""

    while True:
        print(f"\n📍 当前路径: /{current_path}" if current_path else "\n📍 当前路径: / (根目录)")

        items = get_dir_contents(owner, repo, branch, current_path)
        if items is None:
            print("🔙 即将返回上一级...")
            if current_path == "":
                print("⚠️ 已经在根目录，无法返回。退出程序。")
                return
            else:
                current_path = "/".join(current_path.rstrip("/").split("/")[:-1])
                continue

        # 如果当前是一个文件（比如直接访问某个文件路径），直接显示
        if isinstance(items, dict):
            if items['type'] == 'file':
                print(f"\n✅ 已进入文件: {items['name']}")
                print(f"📏 大小: {items['size']} 字节")
                print(f"🔗 下载链接: {items['download_url']}")
                # 尝试显示文本文件内容
                if items['name'].endswith(('.txt', '.py', '.md', '.json', '.yaml', '.yml', '.js', '.html', '.css')):
                    print("\n📝 文件内容预览:\n")
                    try:
                        content_response = requests.get(items['download_url'])
                        content_response.raise_for_status()
                        text = content_response.text
                        print(text[:1000] + "..." if len(text) > 1000 else text)
                    except:
                        print("无法加载文件内容。")
                break
            else:
                print("⚠️ 内容类型异常。")
                return

        # 显示并选择
        chosen = display_and_choose(items, current_path)
        if chosen is None:
            continue

        if chosen == "BACK":
            # 返回上一级
            if current_path == "":
                print("❗ 已经在根目录，无法返回。")
                continue
            else:
                parts = current_path.rstrip("/").split("/")
                current_path = "/".join(parts[:-1])  # 移除最后一级
                print(f"\n🔙 已返回上级目录。")
                continue

        # 处理选择
        if chosen['type'] == 'dir':
            # 进入文件夹
            current_path = chosen['path']  # GitHub API 返回的 path 是完整路径
            print(f"\n📁 进入文件夹: {chosen['name']}")
        elif chosen['type'] == 'file':
            # 选中文件，显示信息
            print(f"\n✅ 已选择文件: {chosen['name']}")
            print(f"📏 大小: {chosen['size']} 字节")
            print(f"🔗 下载链接: {chosen['download_url']}")
            # 预览文本文件
            if chosen['name'].endswith(('.txt', '.py', '.md', '.json', '.yaml', '.yml', '.js', '.html', '.css')):
                print("\n📝 文件内容预览:\n")
                try:
                    content_response = requests.get(chosen['download_url'])
                    content_response.raise_for_status()
                    text = content_response.text
                    print(text[:1000] + "..." if len(text) > 1000 else text)
                except Exception as e:
                    print(f"无法加载内容: {e}")
            break

if __name__ == "__main__":
    main()
